<template>
	<view :id="'tab'+id">
		<scroll-view class="scroll-view_H" scroll-x="true" :scroll-left="scrollLeft">
			<view :id="'tab-item'+index" :class="['scroll-view-item',current==index?'active':'']" :style="[tabItemStyle(index)]"
			 v-for="(item,index) in list" @click="itemClick(item,index)">
				<text :class="item.leftIcon" v-if="!isImg(item.leftIcon)&&item.leftIcon"></text>
				<image class="u-icon__img" v-if="isImg(item.leftIcon)&&item.leftIcon" :src="item.leftIcon" mode="widthFix" :style="[imgStyle]"></image>
				<text style="margin: 0 10rpx;">{{item.name}}</text>
				<text :class="item.rightIcon" v-if="!isImg(item.rightIcon)&&item.rightIcon"></text>
				<image class="u-icon__img" v-if="isImg(item.rightIcon)&&item.rightIcon" :src="item.rightIcon" mode="widthFix"
				 :style="[imgStyle]"></image>
				<view :class="['bar',animation]" :style="barStyle" v-if="(current==index)&&showBar"></view>
			</view>
		</scroll-view>
	</view>
</template>

<script>
	function guid(len = 32, firstU = true, radix = null) {
		let chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
		let uuid = [];
		radix = radix || chars.length;

		if (len) {
			// 如果指定uuid长度,只是取随机的字符,0|x为位运算,能去掉x的小数位,返回整数位
			for (let i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix];
		} else {
			let r;
			// rfc4122标准要求返回的uuid中,某些位为固定的字符
			uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
			uuid[14] = '4';

			for (let i = 0; i < 36; i++) {
				if (!uuid[i]) {
					r = 0 | Math.random() * 16;
					uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
				}
			}
		}
		// 移除第一个字符,并用u替代,因为第一个字符为数值时,该guuid不能用作id或者class
		if (firstU) {
			uuid.shift();
			return 'u' + uuid.join('');
		} else {
			return uuid.join('');
		}
	}
	export default {
		props: {
			current: { //当前选中的tab
				type: [Number, String],
				default: 0
			},
			list: { //tab列表数据
				type: Array,
				default () {
					return []
				}
			},
			barStyle: { //自定义底部横条样式
				type: Object,
				default () {
					return {}
				}
			},
			itemStyle: { //自定义选中项tab的样式
				type: Object,
				default () {
					return {}
				}
			},
			activeColor: { //tab选中字体颜色
				type: String,
				default: 'rgb(41, 121, 255)'
			},
			inactiveColor: { //tab未选中字体颜色
				type: String,
				default: 'rgb(48, 49, 51)'
			},
			showBar: { //是否显示底部的横条
				type: Boolean,
				default: true
			},
			// 用于显示图片小图标时，图片的宽度
			iconWidth: {
				type: [String, Number],
				default: ''
			},
			// 用于显示图片小图标时，图片的高度
			iconHeight: {
				type: [String, Number],
				default: ''
			},
			// 字体大小单位rpx
			fontSize: {
				type: [String, Number],
				default: 30
			}
		},
		data() {
			return {
				scrollLeft: 0,
				animation: '',
				id: guid(10),
				parentLeft:'',
				componentWidth:'',
				tabQueryInfo:[]
			};
		},
		watch:{
			current(){
				setTimeout(() => {
					this.animation = ''
				}, 500)
				this.scrollByIndex()
			}
		},
		computed: {
			tabItemStyle() {
				return (index) => {
					let style = {
						fontSize: this.addUnit(this.fontSize)
					}
					if (index == this.current) {
						style.color = this.activeColor
						Object.assign(style, this.itemStyle);
					} else {
						style.color = this.inactiveColor
					}
					return style
				}
			},
			isImg() {
				return (name) => {
					if (typeof name == 'undefined' || !name) {
						return false
					}
					return name.indexOf('/') !== -1;
				}

			},
			imgStyle() {
				let style = {};
				// 如果设置width和height属性，则优先使用，否则使用size属性
				style.width = this.iconWidth ? this.addUnit(this.width) : this.addUnit(this.fontSize);
				style.height = this.iconHeight ? this.addUnit(this.height) : this.addUnit(this.fontSize);
				return style;
			}
		},
		mounted() {
			this.init()
		},
		methods: {
			// 设置一个init方法，方便多处调用
			init() {
				// 获取tabs组件的尺寸信息
				uni.createSelectorQuery().
				in(this)['select']('#tab' + this.id)
					.boundingClientRect(tabRect => {
						// tabs组件距离屏幕左边的宽度
						this.parentLeft = tabRect.left;
						// tabs组件的宽度
						this.componentWidth = tabRect.width;
						this.getTabRect();
					})
					.exec()
			},
			// 查询tab的布局信息
			getTabRect() {
				// 创建节点查询
				let query = uni.createSelectorQuery().in(this);
				// 历遍所有tab，这里是执行了查询，最终使用exec()会一次性返回查询的数组结果
				for (let i = 0; i < this.list.length; i++) {
					// 只要size和rect两个参数
					// 只要size和rect两个参数
					query.select(`#tab-item${i}`).fields({
						size: true,
						rect: true
					});
				}
				// 执行查询，一次性获取多个结果
				query.exec(
					function(res) {
						this.tabQueryInfo = res;
						// 初始化滚动条和移动bar的位置
						this.scrollByIndex();
					}.bind(this)
				);
			},
			// 滚动scroll-view，让活动的tab处于屏幕的中间位置
			scrollByIndex() {
				// 当前活动tab的布局信息，有tab菜单的width和left(为元素左边界到父元素左边界的距离)等信息
				let tabInfo = this.tabQueryInfo[this.current];
				if (!tabInfo) return;
				// 活动tab的宽度
				let tabWidth = tabInfo.width;
				// 活动item的左边到tabs组件左边的距离，用item的left减去tabs的left
				let offsetLeft = tabInfo.left - this.parentLeft;
				// 将活动的tabs-item移动到屏幕正中间，实际上是对scroll-view的移动
				let scrollLeft = offsetLeft -  tabWidth;
				this.scrollLeft = scrollLeft < 0 ? 0 : scrollLeft;
			},
			addUnit(value = 'auto', unit = 'rpx') {
				value = String(value);
				// 用uView内置验证规则中的number判断是否为数值
				return /^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(value) ? `${value}${unit}` : value;
			},
			itemClick(item, index) {
				this.$emit('click', index)
				if (this.current == index) return
				if (this.current > index) {
					this.animation = 'animate__animated animate__slideInRight'
				} else {
					this.animation = 'animate__animated animate__slideInLeft'
				}
				this.$emit('change', index)

			}
		}
	}
</script>

<style lang="scss">
	.scroll-view_H {
		white-space: nowrap;
	}
	scroll-view ::-webkit-scrollbar {
	  width: 0;
	  height: 0;
	  color: transparent;
	  display: none;
	}

	.scroll-view-item {
		display: inline-block;
		padding: 20rpx 30rpx;
		transition: all 0.2s ease;
	}

	.active {
		position: relative;

		.bar {
			position: absolute;
			left: 0;
			bottom: 0;
			right: 0;
			width: 40%;
			margin: 0 auto;
			height: 4rpx;
			background: #1fb0ac;
			animation-duration: 0.1s;
		}
	}

	.u-icon__img {
		vertical-align: middle;
		display: inline-block;
		bottom: 2rpx;
	}
</style>
